import time
from com.atzl.ui.LogInMonBillUI import Ui_Form
from com.atzl.interaction.WindowNavigation import NavigationWindow
from com.atzl.interaction.WindowMessage import MessageWindow
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QPropertyAnimation, QRect, QEasingCurve
from com.atzl.common.Win import Windows
from com.atzl.common.ActionStates import ActionStates
from com.atzl.common.UsersMessage import MessagesUsers
from com.atzl.common.StatusCode import StatusCode
from com.atzl.functions.accounting.func.Logs import CheckLogs
from com.atzl.functions.accounting.func.LogIn import Loginfun


# 登录窗口交互
class LoginWindow(QMainWindow, Loginfun, CheckLogs): # 继承QMainWindow, Loginfun, CheckLogs


    def __init__(self):
        QMainWindow.__init__(self)

        # 一.初始化控件并将控件设置为全局
        self.ui = Ui_Form()  # 将登录页界面ui初始化并设置为全局
        self.navigation = NavigationWindow()  # 将导航窗口交互初始化并设置为全局
        self.message = MessageWindow()  # 将提示信息窗口交互初始化并设置为全局
        self.m_flag = False  # 初始化鼠标标记符
        self.ui.setupUi(self)  # 加载登录窗口ui类
        self.to_login = None
        global widgets  # 定义全局变量
        widgets = self.ui  # 并将登录页界面ui对象赋值给该全局变量


        # 二.设置控件交互及内在功能

        # 1.设置登录输入框
        my_regex = QtCore.QRegExp("[a-zA-Z0-9]{16}")  # 设置正则
        my_validator = QtGui.QRegExpValidator(my_regex, widgets.lineEdit)  # 定义验证器对象,并将正则对象和用户名输入框对象传入
        my_validator1 = QtGui.QRegExpValidator(my_regex, widgets.lineEdit_2)  # 定义验证器对象,并将正则对象和登录密码输入框对象传入
        widgets.lineEdit.setValidator(my_validator)  # 用户名输入框设置正侧
        widgets.lineEdit_2.setValidator(my_validator1)  # 登录密码输入框设置正侧
        widgets.pushButton_4.clicked.connect(widgets.lineEdit.clear)  # 一键清空用户名输入框内容
        widgets.pushButton_5.clicked.connect(widgets.lineEdit_2.clear)  # 一键清空登录密码输入框内容


        widgets.pushButton_3.clicked.connect(self.showMinimized)  # 登录界面窗口最小化
        widgets.pushButton_2.clicked.connect(self.close_app)  # 关闭应用程序


        widgets.pushButton.clicked.connect(self.logintomain)  # 设置登录按钮触发函数,点击登录验证用户密码判断是否跳转至主页面
        widgets.pushButton.setShortcut(QtCore.Qt.Key_Enter)  # 设置登录按钮被小键盘键盘Enter按键摁下触发事件信号
        widgets.lineEdit_2.setEchoMode(QLineEdit.Password)  # 设置密码输入框文本回显模式


        widgets.pushButton_6.pressed.connect(lambda:  # 点击鼠标左键 更改密码输入框文本回显模式为明文
                                             widgets.lineEdit_2.setEchoMode(QLineEdit.Normal))
        widgets.pushButton_6.released.connect(lambda:  # 释放鼠标左键 更改密码输入框文本回显模式为明文
                                              widgets.lineEdit_2.setEchoMode(QLineEdit.Password))

        # 隐藏界面上所有控件,除开背景控件
        widgets.pushButton.hide()
        widgets.label_3.hide()
        widgets.lineEdit_2.hide()
        widgets.pushButton_5.hide()
        widgets.pushButton_6.hide()
        widgets.label_2.hide()
        widgets.lineEdit.hide()
        widgets.pushButton_4.hide()
        widgets.pushButton_2.hide()
        widgets.pushButton_3.hide()

        # 设置动画对象
        self.anim0 = QPropertyAnimation(widgets.pushButton, b"geometry")
        self.anim1 = QPropertyAnimation(widgets.label_3, b"geometry")
        self.anim2 = QPropertyAnimation(widgets.lineEdit_2, b"geometry")
        self.anim3 = QPropertyAnimation(widgets.pushButton_5, b"geometry")
        self.anim4 = QPropertyAnimation(widgets.pushButton_6, b"geometry")
        self.anim5 = QPropertyAnimation(widgets.label_2, b"geometry")
        self.anim6 = QPropertyAnimation(widgets.lineEdit, b"geometry")
        self.anim7 = QPropertyAnimation(widgets.pushButton_4, b"geometry")

        # 设置控件的几何属性
        self.px = widgets.pushButton.x()  # 设置x轴位置
        self.py = widgets.pushButton.y() + 300  # 设置y轴位置
        self.pw = widgets.pushButton.width()  # 这是控件的宽
        self.ph = widgets.pushButton.height()  # 这是控件的高
        self.pe = widgets.pushButton.geometry()  # 设置为几何属性

        # 同上
        self.lx3 = widgets.label_3.x()
        self.ly3 = widgets.label_3.y() + 300
        self.lw3 = widgets.label_3.width()
        self.lh3 = widgets.label_3.height()
        self.le3 = widgets.label_3.geometry()

        # 同上
        self.lex2 = widgets.lineEdit_2.x()
        self.ley2 = widgets.lineEdit_2.y() + 300
        self.lew2 = widgets.lineEdit_2.width()
        self.leh2 = widgets.lineEdit_2.height()
        self.lee2 = widgets.lineEdit_2.geometry()

        # 同上
        self.px5 = widgets.pushButton_5.x()
        self.pxy5 = widgets.pushButton_5.y() + 300
        self.pw5 = widgets.pushButton_5.width()
        self.ph5 = widgets.pushButton_5.height()
        self.pe5 = widgets.pushButton_5.geometry()

        # 同上
        self.px6 = widgets.pushButton_6.x()
        self.pxy6 = widgets.pushButton_6.y() + 300
        self.pw6 = widgets.pushButton_6.width()
        self.ph6 = widgets.pushButton_6.height()
        self.pe6 = widgets.pushButton_6.geometry()

        # 同上
        self.lx2 = widgets.label_2.x()
        self.ly2 = widgets.label_2.y() + 300
        self.lw2 = widgets.label_2.width()
        self.lh2 = widgets.label_2.height()
        self.le2 = widgets.label_2.geometry()

        # 同上
        self.lx = widgets.lineEdit.x()
        self.ly = widgets.lineEdit.y() + 300
        self.lw = widgets.lineEdit.width()
        self.lh = widgets.lineEdit.height()
        self.le = widgets.lineEdit.geometry()

        # 同上
        self.px4 = widgets.pushButton_4.x()
        self.pxy4 = widgets.pushButton_4.y() + 300
        self.pw4 = widgets.pushButton_4.width()
        self.ph4 = widgets.pushButton_4.height()
        self.pe4 = widgets.pushButton_4.geometry()

        # 重写鼠标单击事件

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.m_flag = True
            self.m_Position = event.globalPos() - self.pos()  # 获取鼠标相对窗口的位置
            event.accept()
            self.setCursor(QCursor(QtCore.Qt.OpenHandCursor))  # 更改鼠标图标



    # 重写鼠标移动事件
    def mouseMoveEvent(self, QMouseEvent):
        if QtCore.Qt.LeftButton and self.m_flag:
            self.move(QMouseEvent.globalPos() - self.m_Position)  # 更改窗口位置
            QMouseEvent.accept()

    # 重写鼠标释放事件
    def mouseReleaseEvent(self, QMouseEvent):
        self.m_flag = False
        self.setCursor(QCursor(QtCore.Qt.ArrowCursor))

    # 重写鼠标接触事件
    def enterEvent(self, event):

        # 禁用中文输入法
        widgets.lineEdit.setAttribute(QtCore.Qt.WA_InputMethodEnabled, False)

        # 显示一开始被隐藏的控件
        widgets.pushButton.show()
        widgets.label_3.show()
        widgets.lineEdit_2.show()
        widgets.pushButton_5.show()
        widgets.pushButton_6.show()
        widgets.label_2.show()
        widgets.lineEdit.show()
        widgets.pushButton_4.show()
        widgets.pushButton_3.show()
        widgets.pushButton_2.show()


        self.anim0 = QPropertyAnimation(widgets.pushButton, b"geometry")  # 设置动画对象
        self.anim0.setDuration(450)  # 设置动画时长
        self.anim0.setStartValue(QRect(self.px,
                                       self.py,
                                       self.pw,
                                       self.ph))  # 设置初始属性
        self.anim0.setEndValue(self.pe)  # 设置结束属性
        self.anim0.setEasingCurve(QEasingCurve.InQuad)
        self.anim0.start()  # 开始动画

        self.anim1 = QPropertyAnimation(widgets.label_3, b"geometry")  # 设置动画对象
        self.anim1.setDuration(450)  # 设置动画时长
        self.anim1.setStartValue(QRect(self.lx3,
                                       self.ly3,
                                       self.lw3,
                                       self.lh3))  # 设置初始属性
        self.anim1.setEndValue(self.le3)  # 设置结束属性
        self.anim1.setEasingCurve(QEasingCurve.InQuad)
        self.anim1.start()  # 开始动画

        self.anim2 = QPropertyAnimation(widgets.lineEdit_2, b"geometry")  # 设置动画对象
        self.anim2.setDuration(450)  # 设置动画时长
        self.anim2.setStartValue(QRect(self.lex2,
                                       self.ley2,
                                       self.lew2,
                                       self.leh2))  # 设置初始属性
        self.anim2.setEndValue(self.lee2)  # 设置结束属性
        self.anim2.setEasingCurve(QEasingCurve.InQuad)
        self.anim2.start()  # 开始动画

        self.anim3 = QPropertyAnimation(widgets.pushButton_5, b"geometry")  # 设置动画对象
        self.anim3.setDuration(450)  # 设置动画时长
        self.anim3.setStartValue(QRect(self.px5,
                                       self.pxy5,
                                       self.pw5,
                                       self.ph5))  # 设置初始属性
        self.anim3.setEndValue(self.pe5)  # 设置结束属性
        self.anim3.setEasingCurve(QEasingCurve.InQuad)
        self.anim3.start()  # 开始动画

        self.anim4 = QPropertyAnimation(widgets.pushButton_6, b"geometry")  # 设置动画对象
        self.anim4.setDuration(450)  # 设置动画时长
        self.anim4.setStartValue(QRect(self.px6,
                                       self.pxy6,
                                       self.pw6,
                                       self.ph6))  # 设置初始属性
        self.anim4.setEndValue(self.pe6)  # 设置结束属性
        self.anim4.setEasingCurve(QEasingCurve.InQuad)
        self.anim4.start()  # 开始动画

        self.anim5 = QPropertyAnimation(widgets.label_2, b"geometry")  # 设置动画对象
        self.anim5.setDuration(450)  # 设置动画时长
        self.anim5.setStartValue(QRect(self.lx2,
                                       self.ly2,
                                       self.lw2,
                                       self.lh2))  # 设置初始属性
        self.anim5.setEndValue(self.le2)  # 设置结束属性
        self.anim5.setEasingCurve(QEasingCurve.InQuad)
        self.anim5.start()  # 开始动画

        self.anim6 = QPropertyAnimation(widgets.lineEdit, b"geometry")  # 设置动画对象
        self.anim6.setDuration(450)  # 设置动画时长
        self.anim6.setStartValue(QRect(self.lx,
                                       self.ly,
                                       self.lw,
                                       self.lh))  # 设置初始属性
        self.anim6.setEndValue(self.le)  # 设置结束属性
        self.anim6.setEasingCurve(QEasingCurve.InQuad)
        self.anim6.start()  # 开始动画
        self.anim7 = QPropertyAnimation(widgets.pushButton_4, b"geometry")  # 设置动画对象
        self.anim7.setDuration(450)  # 设置动画时长
        self.anim7.setStartValue(QRect(self.px4,
                                       self.pxy4,
                                       self.pw4,
                                       self.ph4))  # 设置初始属性
        self.anim7.setEndValue(self.pe4)  # 设置结束属性
        self.anim7.setEasingCurve(QEasingCurve.InQuad)
        self.anim7.start()  # 开始动画

    # 重写鼠标离开事件
    def leaveEvent(self, event):

        # 启用中文输入法
        widgets.lineEdit.setAttribute(QtCore.Qt.WA_InputMethodEnabled, True)

        self.anim0 = QPropertyAnimation(widgets.pushButton, b"geometry")  # 设置动画对象
        self.anim0.setDuration(450)  # 设置动画时长
        self.anim0.setEndValue(QRect(self.px,
                                     self.py,
                                     self.pw,
                                     self.ph))  # 设置初始属性
        self.anim0.setStartValue(self.pe)  # 设置结束属性
        self.anim0.setEasingCurve(QEasingCurve.InQuad)
        self.anim0.start()  # 开始动画

        self.anim1 = QPropertyAnimation(widgets.label_3, b"geometry")  # 设置动画对象
        self.anim1.setDuration(450)  # 设置动画时长
        self.anim1.setEndValue(QRect(self.lx3,
                                     self.ly3,
                                     self.lw3,
                                     self.lh3))  # 设置初始属性
        self.anim1.setStartValue(self.le3)  # 设置结束属性
        self.anim1.setEasingCurve(QEasingCurve.InQuad)
        self.anim1.start()  # 开始动画

        self.anim2 = QPropertyAnimation(widgets.lineEdit_2, b"geometry")  # 设置动画对象
        self.anim2.setDuration(450)  # 设置动画时长
        self.anim2.setEndValue(QRect(self.lex2,
                                     self.ley2,
                                     self.lew2,
                                     self.leh2))  # 设置初始属性
        self.anim2.setStartValue(self.lee2)  # 设置结束属性
        self.anim2.setEasingCurve(QEasingCurve.InQuad)
        self.anim2.start()  # 开始动画

        self.anim3 = QPropertyAnimation(widgets.pushButton_5, b"geometry")  # 设置动画对象
        self.anim3.setDuration(450)  # 设置动画时长
        self.anim3.setEndValue(QRect(self.px5,
                                     self.pxy5,
                                     self.pw5,
                                     self.ph5))  # 设置初始属性
        self.anim3.setStartValue(self.pe5)  # 设置结束属性
        self.anim3.setEasingCurve(QEasingCurve.InQuad)
        self.anim3.start()  # 开始动画

        self.anim4 = QPropertyAnimation(widgets.pushButton_6, b"geometry")  # 设置动画对象
        self.anim4.setDuration(450)  # 设置动画时长
        self.anim4.setEndValue(QRect(self.px6,
                                     self.pxy6,
                                     self.pw6,
                                     self.ph6))  # 设置初始属性
        self.anim4.setStartValue(self.pe6)  # 设置结束属性
        self.anim4.setEasingCurve(QEasingCurve.InQuad)
        self.anim4.start()  # 开始动画

        self.anim5 = QPropertyAnimation(widgets.label_2, b"geometry")  # 设置动画对象
        self.anim5.setDuration(450)  # 设置动画时长
        self.anim5.setEndValue(QRect(self.lx2,
                                     self.ly2,
                                     self.lw2,
                                     self.lh2))  # 设置初始属性
        self.anim5.setStartValue(self.le2)  # 设置结束属性
        self.anim5.setEasingCurve(QEasingCurve.InQuad)
        self.anim5.start()  # 开始动画

        self.anim6 = QPropertyAnimation(widgets.lineEdit, b"geometry")  # 设置动画对象
        self.anim6.setDuration(450)  # 设置动画时长
        self.anim6.setEndValue(QRect(self.lx,
                                     self.ly,
                                     self.lw,
                                     self.lh))  # 设置初始属性
        self.anim6.setStartValue(self.le)  # 设置结束属性
        self.anim6.setEasingCurve(QEasingCurve.InQuad)
        self.anim6.start()  # 开始动画
        self.anim7 = QPropertyAnimation(widgets.pushButton_4, b"geometry")  # 设置动画对象
        self.anim7.setDuration(450)  # 设置动画时长
        self.anim7.setEndValue(QRect(self.px4,
                                     self.pxy4,
                                     self.pw4,
                                     self.ph4))  # 设置初始属性
        self.anim7.setStartValue(self.pe4)  # 设置结束属性
        self.anim7.setEasingCurve(QEasingCurve.InQuad)
        self.anim7.start()  # 开始动画

        widgets.pushButton_2.hide()  # 隐藏关闭按钮
        widgets.pushButton_3.hide()  # 隐藏最小化按钮

    # 跳转至导航页
    def logintomain(self):

        self.get_site()  # 获取IP,MAC,所在地区等信息


        self.to_login = self.login(widgets.lineEdit.text(), widgets.lineEdit_2.text())  # 执行登录功能

        the_time = str(time.strftime("%Y{y}%m{m}%d{d}%H{h}%M{f}%S{s}",  # 生成时间戳
                                     time.localtime())).format(y='年', m='月',
                                                               d='日', h='时',
                                                               s='秒', f='分')
        # 根据登录情况执行页面跳转
        if self.to_login == StatusCode.NORMAL_OPERATION:  # 密码正确
            Windows.NAVIGATION_WIN = self.navigation  # 导航页面对象存入公共模块
            Windows.NAVIGATION_WIN.show()  # 显示导航页面
            self.hide()  # 隐藏登录页面
            Windows.MESSAGE_WIN = self.message  # 消息提示框对象存入公共模块
            Windows.NAVIGATION_WIN.show_anim()  # 执行消息提示框出场动画
            self.in_logs(the_time, ActionStates.LOGTOMAINWIN, MessagesUsers.REAL_NAME)  # 回传用户行为
        elif self.to_login == StatusCode.INCORRECT_PASSWORD:  # 密码错误
            Windows.MESSAGE_WIN = self.message  # 消息提示框对象存入公共模块
            self.to_message(StatusCode.INCORRECT_PASSWORD)  # 弹出消息提示框,提示密码错误
            self.in_logs(the_time, ActionStates.LOGINERRORPASSWORD, widgets.lineEdit.text())  # 回传用户行为
        elif self.to_login == StatusCode.CONNECTDATABASE_PARAMETER:  # 连接数据库参数异常
            Windows.MESSAGE_WIN = self.message  # 消息提示框对象存入公共模块
            self.to_message(StatusCode.CONNECTDATABASE_PARAMETER)  # 弹出消息提示框,连接数据库参数异常
        elif self.to_login == StatusCode.BREAK_DATABASE:  # 与数据库断开连接
            Windows.MESSAGE_WIN = self.message  # 消息提示框对象存入公共模块
            self.to_message(StatusCode.BREAK_DATABASE)  # 弹出消息提示框,与数据库断开连接
        else:  # 未知异常
            Windows.MESSAGE_WIN = self.message  # 消息提示框对象存入公共模块
            self.to_message(StatusCode.UNKONWN_ERROR)  # 弹出消息提示框,未知异常
    # 弹出消息提示窗
    def to_message(self, the_message):
        Windows.MESSAGE_WIN.set_message(the_message)  # 设置提示内容

    # 关闭应用程序
    def close_app(self):
        # 判断是否与数据库是否建立连接
        if self.to_login != StatusCode.NORMAL_OPERATION:  # 断开连接
            self.close()  # 直接关闭应用程序
        else:  # 正常连接
            the_time = str(time.strftime("%Y{y}%m{m}%d{d}%H{h}%M{f}%S{s}",  # 生成时间戳
                                         time.localtime())).format(y='年', m='月',
                                                                   d='日', h='时',
                                                                   s='秒', f='分')
            # 判断用户信息公共模块是否存入真实姓名
            if MessagesUsers.REAL_NAME is not None:  # 没有真实姓名说明用户还没有执行登录操作
                self.in_logs(the_time, ActionStates.CLOSEAPPLICATION, MessagesUsers.REAL_NAME)  # 回传用户行为
            else:  # 存有真实姓名说明用户已经执行登录操作
                self.in_logs(the_time, ActionStates.CLOSEAPPLICATION, widgets.lineEdit.text())  # 回传用户行为
            self.close()  # 关闭应用程序





